﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vds2465Telegrams
{
    // possible TODOs: check that the supportedUserDataTypes
    // - are not empty (?)
    // - contains only known user data types (?, not recommended)
    // - contains not too many items...!
    public class UserData_55_SupportedUserDataTypes : UserData_Device
    {
        #region private member variables

		private readonly SortedSet<byte> _supportedUserDataTypes;

		#endregion private member variables

		#region constructor

		public UserData_55_SupportedUserDataTypes(byte device, SortedSet<byte> supportedUserDataTypes)
			: base(UserData.UserData55SupportedUserDataTypes, device)
		{
			_supportedUserDataTypes = supportedUserDataTypes;
		}

		#endregion constructor

        #region getters

		public SortedSet<byte> SupportedUserDataTypes { get { return _supportedUserDataTypes; } }

        #endregion getters

        #region ToString, Equals, GetHashCode

        public override int GetHashCode()
        {
            int hashCode = base.GetHashCode();

            if (_supportedUserDataTypes != null)
            {
                for (int index = 0; index < _supportedUserDataTypes.Count; index++)
                {
                	hashCode ^= _supportedUserDataTypes.ElementAt(index);
                }
            }

            return hashCode;
        }

        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("(");
            stringBuilder.Append(ToStringProperties());
            stringBuilder.Append(")");

            return stringBuilder.ToString();
        }

        internal override string ToStringProperties()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(base.ToStringProperties());

            stringBuilder.Append(", ");

            stringBuilder.Append("SupportedUserDataTypes='");
            if (_supportedUserDataTypes != null)
            {
				if (_supportedUserDataTypes.Count > 0)
                {
                    stringBuilder.Append("(");
					for (int index = 0; index < _supportedUserDataTypes.Count - 1; index++)
                    {
                        stringBuilder.Append("0x");
						stringBuilder.Append(_supportedUserDataTypes.ElementAt(index).ToString("x2"));
                        stringBuilder.Append(", ");
                    }

                    stringBuilder.Append("0x");
					stringBuilder.Append(_supportedUserDataTypes.ElementAt(_supportedUserDataTypes.Count - 1).ToString("x2"));
                    stringBuilder.Append(")");
                }
                else
                {
                    stringBuilder.Append("<empty>");
                }
            }
            else
            {
                stringBuilder.Append("<null>");
            }

            stringBuilder.Append("'");

            return stringBuilder.ToString();
        }

        public override bool Equals(object obj)
        {
            Type objType = obj.GetType();
            if (GetType() == objType)
            {
                UserData_55_SupportedUserDataTypes userData2Compare = obj as UserData_55_SupportedUserDataTypes;
                return EqualsProperties(userData2Compare);
            }

            return false;
        }

        internal bool EqualsProperties(UserData_55_SupportedUserDataTypes userData2Compare)
        {
            if (base.EqualsProperties(userData2Compare))
            {
                if ((SupportedUserDataTypes != null) && (userData2Compare.SupportedUserDataTypes != null))
                {
                    // compare length
                    if (SupportedUserDataTypes.Count == userData2Compare.SupportedUserDataTypes.Count)
                    {
						for (int index = 0; index < SupportedUserDataTypes.Count; index++)
                        {
                            if (SupportedUserDataTypes.ElementAt(index) != userData2Compare.SupportedUserDataTypes.ElementAt(index))
                            {
                                // difference found
                                return false;
                            }
                        }

                        // all items are equal
                        return true;
                    }

                    // different length
                    return false;
                }
                
                // at least one is null, check this special scenario
                if ((SupportedUserDataTypes == null) && (userData2Compare.SupportedUserDataTypes == null))
                {
                    // both are null, that's fine
                    return true;
                }

                // only one is null: we consider null and an empty byte array to be equal as well
                if (SupportedUserDataTypes == null)
                {
                    return (userData2Compare.SupportedUserDataTypes.Count == 0);
                }
                
				return (SupportedUserDataTypes.Count == 0);
            }

            return false;
        }

        #endregion ToString, Equals, GetHashCode
    }
}
